﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ServiceModel.Syndication;
using System.Linq;
using Nwsfeed;

namespace nwsfeed
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window, INotifyPropertyChanged
	{
        private String windowTitle;
        public String WindowTitle { get { return windowTitle; } set { windowTitle = value; OnPropertyChanged("WindowTitle"); } }
        public event PropertyChangedEventHandler PropertyChanged;
        public Window activeDialog;

        private bool isContentLoading;
        public bool IsContentLoading { get { return isContentLoading; } set { isContentLoading = value; OnPropertyChanged("IsContentLoading"); OnPropertyChanged("RefreshButtonEnabled");} }
      	public bool RefreshButtonEnabled { get {return !isContentLoading;}}
		
        private BackgroundWorker bw1;
        private BackgroundWorker bw2;

        private NwsfeedApp app;
        public NwsfeedApp App 
        {
            get { return app; }
            set { app = value; OnPropertyChanged("App"); listBoxChannels.Items.Refresh(); } 
        }
        AddFeedWindow windowAddFeed;
		ManageFeedsWindow windowManageFeeds;
		SettingsWindow windowSettings;

        // Preferences


        public double TitleFontSize { get { return App.TitleFontSize; } set { App.TitleFontSize = value; OnPropertyChanged("TitleFontSize"); } }
        public double BodyFontSize { get { return App.BodyFontSize; } set { App.BodyFontSize = value; OnPropertyChanged("BodyFontSize"); } }

		public List<FeedItem> Posts
		{
            get 
            {
                if (listBoxChannels.SelectedItem != null)
                    return ((RSSFeed)listBoxChannels.SelectedItem).Posts.ToList();
                else
                    return null;
            }
		}

        public ObservableCollection<RSSFeed> Feeds
        {
            get
            {
                return app.Feeds;
            }
        }

		public MainWindow()
		{
			this.InitializeComponent();
            Loaded += new RoutedEventHandler(MainWindow_Loaded);
			WindowTitle = "nwsfeed";

			
            DataContext = this;
            App = new NwsfeedApp();
            bw1 = new BackgroundWorker();
            bw1.WorkerReportsProgress = true;
            bw1.WorkerSupportsCancellation = true;
            bw1.DoWork += new DoWorkEventHandler(bw1_LoadFeeds);
            bw1.ProgressChanged += new ProgressChangedEventHandler(bw1_LoadFeedsProgressChanged);

            bw2 = new BackgroundWorker();
            bw2.WorkerReportsProgress = true;
            bw2.DoWork += new DoWorkEventHandler(bw2_RefreshFeed);
            bw2.ProgressChanged += new ProgressChangedEventHandler(bw2_UpdateRefreshedFeed);
			
			this.Topmost = true;
			this.Show();
			this.Activate();
			this.Topmost = false;
		}

        void bw2_UpdateRefreshedFeed(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == 0)
                ((RSSFeed)e.UserState).Posts.Clear();
            else
            {
                var updated = e.UserState as RSSFeed;
                var feed = app.Feeds.First(i => i.Uri == updated.Uri);
                if (feed != null)
                {
                    feed.ImageCacheUri = updated.ImageCacheUri;
                    feed.FetchedSuccessfully = updated.FetchedSuccessfully;
                    feed.Posts.Clear();
                    feed.IsLoading = updated.IsLoading;
                    foreach (var item in updated.Posts)
                        feed.Posts.Add(item);
                }
                IsContentLoading = feed.IsLoading;
            }
        }

        void bw2_RefreshFeed(object sender, DoWorkEventArgs e)
        {
            App.LastSelected.IsLoading = true;
            bw2.ReportProgress(0, App.LastSelected);
            IsContentLoading = true;
            RSSFeed _feed = new RSSFeed(App.LastSelected.Uri);
            _feed.Fetch();
            bw2.ReportProgress(100, _feed);
        }

        void bw1_LoadFeeds(object sender, DoWorkEventArgs e)
        {
            foreach (RSSFeed feed in app.Feeds)
                feed.IsLoading = true;

            foreach (RSSFeed feed in app.Feeds)
            {
                if (bw1.CancellationPending)
                    break;
				bw1.ReportProgress(0, feed);
                RSSFeed _feed = new RSSFeed(feed.Uri);
                _feed.Fetch();
                bw1.ReportProgress(100, _feed);
            }
        }

        void bw1_LoadFeedsProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == 0)
            {
                ((RSSFeed)e.UserState).Posts.Clear();
                if (App.LastSelected == ((RSSFeed)e.UserState))
                    IsContentLoading = true;
            }
            else
            {

                var updated = e.UserState as RSSFeed;
                var feed = app.Feeds.First(i => i.Uri == updated.Uri);
                if (feed != null)
                {
                    feed.ImageCacheUri = updated.ImageCacheUri;
                    feed.FetchedSuccessfully = updated.FetchedSuccessfully;

                    feed.IsLoading = updated.IsLoading;



                    foreach (var item in updated.Posts)
                        feed.Posts.Add(item);
                }
                if (feed.Uri == App.LastSelected.Uri)
                    IsContentLoading = feed.IsLoading;
            }
        }

		private void Window_Deactivated(object sender, System.EventArgs e)
		{
            labelWindowTitle.Foreground = new SolidColorBrush(Color.FromRgb(125, 125, 125));
		}

		private void Window_Activated(object sender, System.EventArgs e)
		{
            labelWindowTitle.Foreground = new SolidColorBrush(Color.FromRgb(145, 145, 145));

            if (activeDialog != null)
            {
                activeDialog.Activate();
            }            
		}

        private void buttonAddFeed_Click(object sender, RoutedEventArgs e)
        {
            windowAddFeed = new AddFeedWindow(this);
            windowAddFeed.ShowDialog();
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        private void listBoxChannels_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            if (listBoxChannels.SelectedItem != null)
            {
                app.LastSelected = listBoxChannels.SelectedItem as RSSFeed;
                IsContentLoading = app.LastSelected.IsLoading;

                feedListView.ItemsSource = app.LastSelected.Posts;
                WindowTitle = "nwsfeed - " + app.LastSelected.Title;
            }
			else
			{
                IsContentLoading = false;
				WindowTitle = "nwsfeed";
			}
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var style = (Style)Resources["WindowStyle"];
            this.Style = style;

            App.Initialize();
            //App.loadSampleFeed();

            // load feeds and settings from disk
            App.LoadProfileSettings();
            if (app.LastSelected.Uri != null)
                listBoxChannels.SelectedItem = app.LastSelected;

            // load feeds asynchronously
            bw1.RunWorkerAsync(false);
        }

            
        private void appImage_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left && appImage != null && appImage.ContextMenu != null)
			{
                appImage.ContextMenu.PlacementTarget = appImage;
                appImage.ContextMenu.HorizontalOffset = -12;
                appImage.ContextMenu.VerticalOffset = 7;
                appImage.ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
                ContextMenuService.SetVerticalOffset(appImage, 7);
                ContextMenuService.SetHorizontalOffset(appImage, -12);
                ContextMenuService.SetPlacement(appImage, System.Windows.Controls.Primitives.PlacementMode.Bottom);                
				appImage.ContextMenu.IsOpen = true;
                e.Handled = true;
			}
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            app.SaveProfileSettings();
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	this.bw2.RunWorkerAsync();
        }

        private void AddButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	windowAddFeed = new AddFeedWindow(this);
            windowAddFeed.ShowDialog();
        }

        private void MenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	// TODO: Add event handler implementation here.
			windowManageFeeds = new ManageFeedsWindow(this);
			windowManageFeeds.ShowDialog();
            if (windowManageFeeds.OpenAddFeedsWindow)
                AddButton_Click(this, null);
        }

        private void AddMenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	AddButton_Click(this, null);
        }

        private void PreferencesMenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
        {
        	windowSettings = new SettingsWindow(this);
			windowSettings.ShowDialog();
        }

        private void RefreshMenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (bw2.IsBusy)
                bw2.CancelAsync();
            bw2.RunWorkerAsync();
        }

        private void RefreshAllMenuItem_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (bw1.IsBusy)
                bw1.CancelAsync();
        	bw1.RunWorkerAsync();
        }

        private void textBlock_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var block = sender as TextBlock;
            System.Diagnostics.Process.Start(block.Tag as String);
        }

	}
}